package com.example.nio.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.RedisStringCommands;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.types.Expiration;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;

import java.util.Objects;

@Component
public class RedisConfig {
    private static final long LOCKTIME = System.currentTimeMillis();

    @Autowired
    private RedisTemplate redisTemplate;

    public boolean setNx(String key,String val,int time) {
        return (Boolean) redisTemplate.execute((RedisCallback) connection -> {
            Boolean acquire = connection.set(key.getBytes(),val.getBytes(), Expiration.seconds(time),RedisStringCommands.SetOption.ifAbsent());
            if (acquire) {
                //设置成功标识没有锁
                return true;
            } else {
                //已加锁
                byte[] value = connection.get(key.getBytes());
                if (Objects.nonNull(value) && value.length > 0) {
                    long expireTime = Long.parseLong(new String(value));
                    if (expireTime < System.currentTimeMillis()) {
                        // 加锁时间过期
                        byte[] oldValue = connection.getSet(key.getBytes(), String.valueOf(System.currentTimeMillis() + time).getBytes());
                        // 防止死锁
                        return Long.parseLong(new String(oldValue)) < System.currentTimeMillis();
                    }
                }
            }
            return false;
        });
    }
    /**
     * 通过使用redis默认的序列化获取String类型的值
     *
     * @param key 键
     * @return String类型的值
     */
    public String getStringBySer(String key) {
        try {
            return (String) redisTemplate.execute((RedisCallback<String>) connection -> {
                RedisSerializer<String> serializer = redisTemplate.getStringSerializer();
                byte[] serialize = serializer.serialize(key);
                if (serialize == null) {
                    return null;
                }
                byte[] value = connection.get(serialize);
                return serializer.deserialize(value);
            });
        } catch (Exception e) {
            return null;
        }
    }
    public boolean removeKey(String key){
        return redisTemplate.delete(key);
    }
    /**
     * 递减
     * @param key 键
     * @return
     */
    public long decr(String key, long delta){
        if(delta<0){
            throw new RuntimeException("递减因子必须大于0");
        }
        return redisTemplate.opsForValue().increment(key, -delta);
    }
    /**
     * 递增
     * @param key 键
     * @return
     */
    public long incr(String key, long delta){
        if(delta<0){
            throw new RuntimeException("递增因子必须大于0");
        }
        return redisTemplate.opsForValue().increment(key, delta);
    }
}
